package org.one.stone.soup.grfxML;

import org.one.stone.soup.mjdb.data.field.DataLinker;
import org.one.stone.soup.mjdb.data.field.Field;
import org.one.stone.soup.mjdb.data.field.LockException;
import org.one.stone.soup.mjdb.data.field.NullField;
import org.one.stone.soup.xml.XmlElement;
  /*
 * Copyright 2000-2001 Wet-Wired.com Ltd.,
 * Portsmouth England
 * All rights reserved.
 */

/**
	*
	* @author Nik Cross
*/
public class DataTranslation extends NullField implements ITag {
	public static String DEFAULT_ID = "_Translation";

		DataState visible = new DataState(true);
		private DataState visibleLast = new DataState(true);
		DataState visibleView = new DataState(true);

		DataPoint position = new DataPoint();
		DataPoint positionLast = new DataPoint(-1,-1);
		DataPoint positionView = new DataPoint();

		DataSize rotation = new DataSize(TagModifier.SIZE_TYPE_ANGLE);
		DataSize rotationLast = new DataSize(TagModifier.SIZE_TYPE_ANGLE);
		DataSize rotationView = new DataSize(TagModifier.SIZE_TYPE_ANGLE);

		DataScale scale = new DataScale(1);
		DataScale scaleLast = new DataScale(1);
		DataScale scaleView = new DataScale(1);

		DataPoint window = new DataPoint();

		private boolean _windowDefined = false;
		private boolean _translated = false;
		protected boolean hasChanges = false;
public DataTranslation() {
	try{
		setId(DEFAULT_ID,this);
	}
	catch(LockException le){} //Dummy catch
}
public void buildFromgrfxML(XmlElement xml)
{

	String name = xml.getAttributeValueByName(Token.ID);
	if(name!=null)
	{
		try{
			setId(name,this);
		}
		catch(LockException le){} //Dummy catch
	}

	XmlElement element;

	for(int loop=0;loop<xml.getElementCount();loop++)
	{
		element = xml.getElementByIndex(loop);
		if(element == null)
			continue;

		String eleName = element.getName();

		if(eleName.equals(Token.VISIBLE))
		{
			visible = new DataState(true);
			visible.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.POSITION))
		{
			position = new DataPoint();
			position.buildFromgrfxML(element,TagModifier.POINT_TYPE_POINT);
		}
		else if(eleName.equals(Token.ROTATION))
		{
			rotation = new DataSize(TagModifier.SIZE_TYPE_ANGLE);
			rotation.buildFromgrfxML(element,TagModifier.SIZE_TYPE_ANGLE);
		}
		else if(eleName.equals(Token.SCALE))
		{
			scale = new DataScale(1);
	  		scale.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.WINDOW))
		{
			window = new DataPoint(TagModifier.POINT_TYPE_BOUNDS);
			window.buildFromgrfxML(element,TagModifier.POINT_TYPE_BOUNDS);
			_windowDefined = true;
		}
		else if( !NameHelper.isSystemName(element.getName()) )
		{
			GrfxMLException.warning( GrfxMLException.WARNING_UNRECOGNISED_TAG_CODE ,new Object[]{eleName,Token.TRANSLATION,""+element.getStartLineNo()} );
		}
	}
}
public void copyFromgrfxML(XmlElement xml)
{
	XmlElement element;

	for(int loop=0;loop<xml.getElementCount();loop++)
	{
		element = xml.getElementByIndex(loop);
		if(element == null)
			continue;

		String eleName = element.getName();

		if(eleName.equals(Token.VISIBLE))
		{
			visible.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.POSITION))
		{
			position.copyFromgrfxML(element,TagModifier.POINT_TYPE_POINT);
		}
		else if(eleName.equals(Token.ROTATION))
		{
			rotation.copyFromgrfxML(element,TagModifier.SIZE_TYPE_ANGLE);
		}
		else if(eleName.equals(Token.SCALE))
		{
	  		scale.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.WINDOW))
		{
			window.copyFromgrfxML(element);
			_windowDefined=true;
		}
		else
		{
			GrfxMLException.warning( GrfxMLException.WARNING_UNRECOGNISED_TAG_CODE ,new Object[]{eleName,Token.TRANSLATION,""+element.getStartLineNo()} );
		}
	}
}
public DataTranslation getClone() {

	DataTranslation newTranslation = new DataTranslation();

	newTranslation.position = position.getClone(TagModifier.POINT_TYPE_POINT);
	newTranslation.rotation = rotation.getClone(TagModifier.SIZE_TYPE_ANGLE);
	newTranslation.scale = scale.getClone();
	newTranslation.visible = visible.getClone();
	newTranslation.window = window.getClone(TagModifier.POINT_TYPE_BOUNDS);
	newTranslation._windowDefined = _windowDefined;

	return newTranslation;
}
public DataTranslation getClone(String path) {

	DataTranslation newTranslation = new DataTranslation();

	GrfxMLStoreProcessor.setCloneName( path,this,newTranslation );

	newTranslation.position = position.getClone(TagModifier.POINT_TYPE_POINT,path);
	newTranslation.rotation = rotation.getClone(TagModifier.SIZE_TYPE_ANGLE,path);
	newTranslation.scale = scale.getClone(path);
	newTranslation.visible = visible.getClone(path);
	newTranslation.window = window.getClone(TagModifier.POINT_TYPE_BOUNDS,path);
	newTranslation._windowDefined = _windowDefined;

	return newTranslation;
}
public DataPoint getPosition() {
	return position;
}
/**
 *
 * @return org.one.stone.soup.grfxML.DataPoint
 */
public DataPoint getPositionView() {
	return positionView;
}
public DataSize getRotation() {
	return rotation;
}
public DataScale getScale() {
	return scale;
}
public DataState getVisible() {
	return visible;
}
public DataPoint getWindow() {
	return window;
}
public void register(DataLinker store) {

	super.register(store);

	try{
		store.add(visible,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(position,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(rotation,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(scale,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(window,this);
	}
	catch(LockException le)
	{}//Dummy catch
}
public void replace(Field oldObj, Field newObj) {
	replace(oldObj, newObj, false);
}
public void replace(Field oldObj, Field newObj,boolean recursive) {

	if(visible==oldObj)
		visible=(DataState)newObj;

	if(position==oldObj)
		position=(DataPoint)newObj;

	if(rotation==oldObj)
		rotation=(DataSize)newObj;

	if(scale==oldObj)
		scale=(DataScale)newObj;

	if(window==oldObj)
	{
		window=(DataPoint)newObj;
		_windowDefined = true;
	}

}

public void resetChanged() {
	_translated = false;

	//visible.resetChanged();
	//visibleView.resetChanged();
	/*position.resetChanged();
	positionView.resetChanged();
	rotation.resetChanged();
	rotationView.resetChanged();
	scale.resetChanged();
	scaleView.resetChanged();*/
}

public void setChanged()
{
	hasChanges = true;
}

protected void setPosition(DataPoint newPosition) {
	position = newPosition;
}
/**
 *
 * @param newPositionView org.one.stone.soup.grfxML.DataPoint
 */
protected void setPositionView(DataPoint newPositionView) {
	positionView = newPositionView;
}
protected void setRotation(DataSize newRotation) {
	rotation = newRotation;
}
protected void setScale(DataScale newScale) {
	scale = newScale;
}
protected void setVisible(DataState newVisible) {
	visible = newVisible;
}
protected void setWindow(DataPoint newWindow) {
	window = newWindow;
	_windowDefined=true;
}
public String togrfxML(String name) {
	String xml = "<" + name + ">";
	xml += visible.togrfxML(DataState.TRUE,Token.VISIBLE);
	xml += position.togrfxML(Token.POSITION,TagModifier.POINT_TYPE_POINT);
	xml += rotation.togrfxML(Token.ROTATION,TagModifier.SIZE_TYPE_ANGLE);
	xml += scale.togrfxML(new DataScale(1),Token.SCALE);
	
	if(_windowDefined==true)
	{
		xml += window.togrfxML(Token.WINDOW,TagModifier.POINT_TYPE_BOUNDS);
	}
	xml += "</" + name + ">\n";
	return xml;
}
public String togrfxML(String name,TagModifier modifier) {
	return togrfxML(name);
}
public String toString()
{
	if(GrfxMLEngine.DEBUG)
		return(togrfxML( DEFAULT_ID.substring(1) ));

	String xml = "<"+DEFAULT_ID.substring(1)+"/>";

	return xml;
}
public void translate(DataTranslation t) {

	if(_translated==false)
	{
		hasChanges = t.hasChanges;

		if( hasChanges || visible.getValue() != visibleLast.getValue())
		{
			try {
				GrfxMLProcessor.translate(visible, t, visibleView);

				visibleLast.setValue( visible.getValue(),this );
				hasChanges=true;
			}
			catch (LockException le)
			{
				le.printStackTrace();
			}
		}

		if(visibleView.getValue()==false)
			return;

		if( hasChanges ||  position.getValueX()!=positionLast.getValueX() || position.getValueY()!=positionLast.getValueY())
		{
			try {
				GrfxMLProcessor.translate(position,TagModifier.POINT_TYPE_POINT, t, positionView);

				positionLast.setValueX( position.getValueX(),this );
				positionLast.setValueY( position.getValueY(),this );
				hasChanges=true;
			}
			catch (LockException le)
			{
				le.printStackTrace();
			}
		}

		if( hasChanges || rotation.getValue()!=rotationLast.getValue() )
		{
			try {
				GrfxMLProcessor.translate(rotation,TagModifier.SIZE_TYPE_ANGLE, t, rotationView);

				rotationLast.setValue( rotation.getValue(),this );
				hasChanges=true;
			}
			catch (LockException le)
			{
				le.printStackTrace();
			}
		}

		if( hasChanges || scale.getValue()!=scaleLast.getValue() )
		{
			try {
				GrfxMLProcessor.translate(scale, t, scaleView);

				scaleLast.setValue( (float)scale.getValue(),this );
				hasChanges=true;
			}
			catch (LockException le)
			{
				le.printStackTrace();
			}
		}

/*		if(_windowDefined)
		{
			window.setValueXMin( positionView.getValueX() );
			window.setValueYMin( positionView.getValueY() );
		}
		else*/
		if(_windowDefined==false)
		{
			try{
				window.setValueX( t.window.getValueX(),this );
				window.setValueY( t.window.getValueY(),this );
				window.setValueXMin( t.window.getValueXMin() );
				window.setValueYMin( t.window.getValueYMin() );

				_windowDefined = t.isWindowDefined();
			}
			catch(LockException le)
			{
				le.printStackTrace();
			}
		}

		_translated = true;
	}
}

	public boolean isWindowDefined()
	{
		return _windowDefined;
	}

	public boolean inWindow(DataPoint point)
	{
		int x = point.getValueX();
		int y = point.getValueY();

		int startX = window.getValueXMin();
		int startY = window.getValueYMin();

		int w = window.getValueX();
		int h = window.getValueY();

		if(
			x > startX &&
			y > startY &&
			x < startX+w &&
			y < startY+h
		)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}
